package it.unica.informatica.enotes.notes;

import android.os.Parcel;
import android.os.Parcelable;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

/**
 * This class manages a typical note and its contents
 * @author Mirko Marras
 * @version 1.0
 */

public class Note implements Parcelable, Comparable<Note> {

    private Long id;
    private String title;
    private String content;
    private String lastChange;
    private ArrayList<String> tags;
    private ArrayList<AttachmentItem> attachments;

    /**
     * Construct a new note object with default values
     */
    public Note(){
        this.id = Long.valueOf(0);
        this.title = "";
        this.content = "";
        this.attachments = new ArrayList<AttachmentItem>();
        this.tags = new ArrayList<String>();
    }

    /**
     * Construct a new note object with the values passed as parameters
     * @param id The id of the new note
     * @param title The title of the new note
     * @param lastChange The date of the last change of the new note
     */
    public Note(Long id, String title, String lastChange) {
        this.id = id;
        this.title = title;
        this.lastChange = lastChange;
        this.content = "";
        this.attachments = new ArrayList<AttachmentItem>();
        this.tags = new ArrayList<String>();
    }

    /**
     * Get the id of this note object
     * @return The id of the note object
     */
    public Long getId() {
        return this.id;
    }

    /**
     * Set the id of this note object
     * @param id The new id for the note object
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * Get the title of this note object
     * @return The title of the note object
     */
    public String getTitle(){
        return this.title;
    }

    /**
     * Set the title of this note object
     * @param title The new title for the note object
     */
    public void setTitle(String title){
        this.title = title;
    }

    /**
     * Get the text content of this note object
     * @return The text content of the note object
     */
    public String getContent(){
        return this.content;
    }

    /**
     * Set the text content of this note object
     * @param content The new text content for the note object
     */
    public void setContent(String content){
        this.content = content;
    }

    /**
     * Get the date of the last change of this note object
     * @return The date of the last change of the note object as a formatted string
     */
    public String getLastChange() {
        return this.lastChange;
    }

    /**
     * Get the date of the last change of this note object
     * @return The date of the last change of the note object as a formatted string
     */
    public String getLastChangeFormatter() {
        return this.lastChange;
    }

    /**
     * Set the date of the last change of this note object
     * @param lastChange The new date of the last change of the note object
     */
    public void setLastChange (String lastChange) {
        this.lastChange = lastChange;
    }

    /**
     * Get the list of all the tags associated to this note object
     * @return The list of all the tags for the note object
     */
    public ArrayList<String> getTags (){
        return this.tags;
    }

    /**
     * Set the list of all the tags associated to this note object
     * @param tags The new list of tags associated to the note object
     */
    public void setTag (ArrayList<String> tags) {
        this.tags = (ArrayList<String>) tags.clone();
    }

    /**
     * Get the list of all the attachments associated to this note object
     * @return The list of all the attachments for the note object
     */
    public ArrayList<AttachmentItem> getAttachments() {
        return this.attachments;
    }

    /**
     * Set the list of all the attachments associated to this note object
     * @param attachments The new list of attachments associated to the note object
     */
    public void setAttachments (ArrayList<AttachmentItem> attachments) {
        this.attachments = (ArrayList<AttachmentItem>) attachments.clone();
    }

    /**
     * Check if the note object is empty
     * @return True if the note object is empty, false otherwise
     */
    public boolean isEmpty() {
        return  this.title.equals("");
    }

    /**
     * Compare this note object with another based on the date of the last change
     * Added by Massimiliano Meles
     * @param another The second note object to compare with this
     * @return A negative value if the date of the last change of this note object precedes another last change,
     *         a position value if it is after the another last change or 0 if they are the same
     */
    @Override
    public int compareTo(Note another) {



        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss dd/MM/yyyy");
        Date date1=null;
        Date date2=null;

        try {
            date1 = format.parse(another.lastChange);
            date2 = format.parse(lastChange);
        }catch(ParseException e){}


        return date1.compareTo(date2);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Note)) return false;

        Note note = (Note) o;

        if (!attachments.equals(note.attachments)) return false;
        if (!content.equals(note.content)) return false;
        if (!tags.equals(note.tags)) return false;
        if (!title.equals(note.title)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = title.hashCode();
        result = 31 * result + content.hashCode();
        result = 31 * result + tags.hashCode();
        result = 31 * result + attachments.hashCode();
        return result;
    }

    /**********************************************************************************************
     *                                        PARCELABLE METHODS                                  *
     **********************************************************************************************/

    public static final Parcelable.Creator<Note> CREATOR
            = new Parcelable.Creator<Note>() {
        public Note createFromParcel(Parcel in) {
            return new Note(in);
        }

        public Note[] newArray(int size) {
            return new Note[size];
        }
    };

    /**
     * Describe the content of the parcelable
     * @return Always zero
     */
    public int describeContents() {
        return 0;
    }

    /**
     * Save a note in the parcelable
     * @param out The output parcelable
     * @param flags Flags used to save
     */
    public void writeToParcel(Parcel out, int flags) {
        out.writeLong(id);
        out.writeString(title);
        out.writeString(content);
        out.writeString(lastChange);
        out.writeStringList(tags);
        out.writeTypedList(attachments);
    }

    /**
     * Recreate a note from the parcelable
     * @param in The parcelable where read
     */
    private Note(Parcel in) {
        this.id = in.readLong();
        this.title = in.readString();
        this.content = in.readString();
        this.lastChange = in.readString();
        in.readStringList(tags);
        in.readTypedList(attachments, AttachmentItem.CREATOR);
    }
}
